﻿//  Copyright (c) 2011 Ray Liang (http://www.dotnetage.com)
//  Licensed MIT: http://www.opensource.org/licenses/mit-license.php

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Web;

namespace DNA.Mvc.Community
{
    public class ForumWrapper : Forum, IHierarchyData,IHierarchicalEnumerable
    {
        private IForumContext context;
        private Forum innerForum;

        public ForumWrapper(Forum forum, IForumContext _context)
        {
            context = _context;
            innerForum = forum;
        }
        
        public virtual IForumContext Context { get { return context; } }

        #region Overwrites

        public override int ID
        {
            get
            {
                return innerForum.ID;
            }
            set
            {
                innerForum.ID = value;
            }
        }

        public override bool AllowAnonymous
        {
            get
            {
                return innerForum.AllowAnonymous;
            }
            set
            {
                innerForum.AllowAnonymous = value;
            }
        }

        public override bool AllowAttachment
        {
            get
            {
                return innerForum.AllowAttachment;
            }
            set
            {
                innerForum.AllowAttachment = value;
            }
        }

        public override string Description
        {
            get
            {
                return innerForum.Description;
            }
            set
            {
                innerForum.Description = value;
            }
        }

        public override string ImageUrl
        {
            get
            {
                return innerForum.ImageUrl;
            }
            set
            {
                innerForum.ImageUrl = value;
            }
        }

        public override bool IsGroup
        {
            get
            {
                return innerForum.IsGroup;
            }
            set
            {
                innerForum.IsGroup = value;
            }
        }

        public override bool IsLocked
        {
            get
            {
                return innerForum.IsLocked;
            }
            set
            {
                innerForum.IsLocked = value;
            }
        }

        public override bool IsModerated
        {
            get
            {
                return innerForum.IsModerated;
            }
            set
            {
                innerForum.IsModerated = value;
            }
        }

        public override string Language
        {
            get
            {
                return innerForum.Language;
            }
            set
            {
                innerForum.Language = value;
            }
        }

        public override string Theme
        {
            get
            {
                return innerForum.Theme;
            }
            set
            {
                innerForum.Theme = value;
            }
        }

        public override int TotalPosts
        {
            get
            {
                return innerForum.TotalPosts;
            }
            set
            {
                innerForum.TotalPosts = value;
            }
        }

        public override string Title
        {
            get
            {
                return innerForum.Title;
            }
            set
            {
                innerForum.Title = value;
            }
        }

        public override ICollection<Thread> Threads
        {
            get
            {
                return innerForum.Threads;
            }
            set
            {
                innerForum.Threads = value;
            }
        }

        public override int Pos
        {
            get
            {
                return innerForum.Pos;
            }
            set
            {
                innerForum.Pos = value;
            }
        }

        public override int ParentID
        {
            get
            {
                return innerForum.ParentID;
            }
            set
            {
                innerForum.ParentID = value;
            }
        }

        public override int LastPostID
        {
            get
            {
                return innerForum.LastPostID;
            }
            set
            {
                innerForum.LastPostID = value;
            }
        }

        public override ICollection<Moderator> Moderators
        {
            get
            {
                return innerForum.Moderators;
            }
            set
            {
                innerForum.Moderators = value;
            }
        }

        #endregion

        #region Implement IHierarchyData

        IHierarchicalEnumerable IHierarchyData.GetChildren()
        {
            return this;
        }

        IHierarchyData IHierarchyData.GetParent()
        {
            if (this.ParentID > 0)
            {
                var parent = context.Forums.Find(ParentID);
                if (parent != null)
                {
                    return new ForumWrapper(parent, context);
                }
            }
            return null;
        }

        bool IHierarchyData.HasChildren
        {
            get
            {
                return this.HasChildren;
            }
        }

        object IHierarchyData.Item
        {
            get
            {
                return this.innerForum;
            }
        }

        string IHierarchyData.Path
        {
            get { return this.ID.ToString(); }
        }

        string IHierarchyData.Type
        {
            get
            {
                if (this.IsGroup)
                    return "Group";
                else
                    return "Forum";
            }
        }

        #endregion

        #region Implement IHierarchialEnumerable

        IHierarchyData IHierarchicalEnumerable.GetHierarchyData(object enumeratedItem)
        {
            return this;
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return context.Forums.Filter(f => f.ParentID == ParentID).GetEnumerator();
        }

        #endregion

        public bool HasChildren
        {
            get
            {
                return context.Forums.Count(f => f.ParentID == this.ID) > 0;
            }
        }

        public Post LastPost
        {
            get
            {
               if (LastPostID > 0)
                   return context.Posts.Find(LastPostID);
               return null;
            }
        }

        public int TotalThreads
        {
            get
            {
                if (Threads != null)
                    return Threads.Count;
                return 0;
            }
        }

        private int unapproveThreads=-1;
        private int unapprovePosts=-1;

        public int UnapproveThreads
        {
            get
            {
                if (unapproveThreads == -1)
                    unapproveThreads = this.Threads.Count(t => !t.IsApproved);
                return unapproveThreads;
            }
        }

        public int UnapprovePosts
        {
            get
            {
                if (unapprovePosts == -1)
                    unapprovePosts = context.Posts.Count(p => !p.IsApproved && p.ForumID == ID);
                return unapprovePosts;
            }
        }

        /// <summary>
        /// Identity current user is moderator of this forum
        /// </summary>
        /// <param name="forum"></param>
        public bool IsModerator(HttpContextBase httpContext)
        {
            if (httpContext.Request.IsAuthenticated)
            {
                if (HttpContext.Current.User.IsInRole("administrators"))
                    return true;

                return Moderators.FirstOrDefault(m => m.UserName.Equals(httpContext.User.Identity.Name)) != null;
            }
            return false;
        }

        public IEnumerable<ForumGroup> SubGroups
        {
            get
            {
                return context.Forums.Filter(f => f.IsGroup && f.ParentID == this.ID)
                    .OrderBy(f => f.Pos)
                    .ToList()
                    .Select(f => new ForumGroup(f, context));
            }
        }

        public IEnumerable<ForumWrapper> SubForums
        {
            get
            {
                return context.Forums.Filter(f => f.ParentID == ID && !f.IsGroup)
                    .OrderByDescending(f => f.Pos)
                    .ToList()
                    .Select(f => new ForumWrapper(f, context));
            }
        }
    }
}
